package com.david.core.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View

class MySeekBar(context: Context, attr: AttributeSet) : View(context, attr) {
    val paint = Paint()

    private var draggingProgress: Float = 0f
    var progress: Float = 50f
        set(value) {
            field = value
            postInvalidate()
        }

    var max: Float = 100f

    var onMySeekBarChangeListener: OnMySeekBarChangeListener? = null

    private var circleRadius = 0f
    private var lineWidth = 0f
    private var lineStart = 0f
    private var lineTop = 0f
    private var lineBottom = 0f

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        circleRadius = (measuredHeight - paddingTop - paddingBottom) / 2f
        lineWidth = (measuredWidth - circleRadius - circleRadius - paddingStart - paddingEnd)
        lineStart = circleRadius + paddingLeft
        lineTop = 15f + paddingTop
        lineBottom = measuredHeight - paddingBottom - 15f
    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        paint.color = Color.WHITE
        canvas.drawRect(lineStart, lineTop, width.toFloat() - circleRadius - paddingEnd, lineBottom, paint)

        paint.color = Color.RED

        if (isDragging) {
            canvas.drawRect(lineStart, lineTop, (lineWidth * (draggingProgress / max)) + lineStart, lineBottom, paint)

            canvas.drawCircle((lineWidth * (draggingProgress / max)) + lineStart, circleRadius + paddingTop, circleRadius, paint)
        } else {
            canvas.drawRect(lineStart, lineTop, (lineWidth * (progress / max)) + lineStart, lineBottom, paint)

            canvas.drawCircle((lineWidth * (progress / max)) + lineStart, circleRadius + paddingTop, circleRadius, paint)
        }
    }

    private var isDragging = false
    private var downTime = 0L
    private var downX = 0f

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when(event?.action) {
            MotionEvent.ACTION_DOWN -> {
                downTime = System.currentTimeMillis()
                downX = event.x

                isDragging = true
            }
            MotionEvent.ACTION_MOVE -> {
                draggingProgress = (event.x - circleRadius - paddingStart) / lineWidth * max
                if (draggingProgress < 0) {
                    draggingProgress = 0f
                } else if (draggingProgress > max) {
                    draggingProgress = max
                }

                postInvalidate()

                onMySeekBarChangeListener?.onProgressChanging(draggingProgress)
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                isDragging = false

                progress = (event.x - circleRadius - paddingStart) / lineWidth * max

                if (progress < 0) {
                    progress = 0f
                } else if (progress > max) {
                    progress = max
                }
                postInvalidate()

                onMySeekBarChangeListener?.onProgressChanged(progress)
            }
        }
        return true
    }
}

interface OnMySeekBarChangeListener{
    fun onProgressChanged(progress: Float)
    fun onProgressChanging(progress: Float)
}